
%inline
%{
#include <string>
#include <istream>
#include <ostream>
#include "google/protobuf/io/zero_copy_stream.h"
#include "google/protobuf/io/zero_copy_stream_impl.h"
%}


%include "protobuf_typemaps.i"
%include "zero_copy_stream.i"


%include "carrays.i"
%include "cdata.i"
%include "cstring.i"

namespace google
{
   namespace protobuf
   {
       namespace io
       {




class FileInputStream : public ZeroCopyInputStream 
{
   public:
      explicit FileInputStream(int file_descriptor, int block_size = -1);
      ~FileInputStream();
 
      bool Close();
 
      void SetCloseOnDelete(bool value);
  
      int GetErrno() { return copying_input_.GetErrno(); }
  
      //bool Next(const void** data, int* size);
      void BackUp(int count);
      bool Skip(int count);
      ::google::protobuf::int64 ByteCount() const;
};




/*
%typemap(argout) (void **OutArray, int *OutValue)
{
    
    PyObject *o2, *o3;
    PyObject *pyBytesObj;
    Py_buffer view;
   
  
    
    
    pyBytesObj = (PyObject*)PyObject_New(PyByteArrayObject, &PyByteArray_Type);
    
    printf("%x %d\n", *$1, *$2);
    memset(*$1, 0x04, *$2);
    
    printf("%x\n", pyBytesObj);
   
    pyBytesObj = (PyObject*)PyObject_InitVar((PyVarObject*)pyBytesObj, &PyBytes_Type, *$2);
    
    
    
    if(PyObject_GetBuffer(pyBytesObj, &view, 0) != 0)
    {
        printf("Error1\n");
    }
   
    if(PyBuffer_FillInfo(&view, NULL, (void*)"Hell", *$2, 1, PyBUF_C_CONTIGUOUS) != 0)
    {
        printf("Error2\n");
    }
    
    pyBytesObj = PyBytes_FromFormat("%p", *$1);
     
    
    printf("%x\n", pyBytesObj);
    
    $result = pyBytesObj;
    
  
    
    if((!$result) || ($result == Py_None)) 
    {
        $result = pyBytesObj;
    }else 
    {
        if (!PyTuple_Check($result)) 
        {
            PyObject *o2 = $result;
            $result = PyTuple_New(1);
            PyTuple_SetItem($result,0,o2);
        }
        o3 = PyTuple_New(1);
        PyTuple_SetItem(o3,0,pyBytesObj);
        o2 = $result;
        $result = PySequence_Concat(o2,o3);
        Py_DECREF(o2);
        Py_DECREF(o3);
    }
    
    
}


%typemap(in,numinputs=0) void **OutArray(void *temp) 
{
    $1 = &temp;
}

%typemap(in,numinputs=0) int *OutValue(int temp) 
{
    $1 = &temp;
}


*/


class FileOutputStream : public ZeroCopyOutputStream 
{
    public:
      explicit FileOutputStream(int file_descriptor, int block_size = -1);
      ~FileOutputStream();

      bool Close();
      bool Flush();
      void SetCloseOnDelete(bool value); 
      int GetErrno();
      //bool Next(void** OutArray, int* OutValue);
      void BackUp(int count);
      ::google::protobuf::int64 ByteCount() const;
};

class IstreamInputStream : public ZeroCopyInputStream 
{
    public:
      explicit IstreamInputStream(::std::istream* stream, int block_size = -1);
      ~IstreamInputStream();

      //bool Next(const void** data, int* size);
      void BackUp(int count);
      bool Skip(int count);
      ::google::protobuf::int64 ByteCount() const;
};

class OstreamOutputStream : public ZeroCopyOutputStream 
{
    public:
      explicit OstreamOutputStream(::std::ostream* stream, int block_size = -1);
      ~OstreamOutputStream();

      //bool Next(void** data, int* size);
      void BackUp(int count);
      ::google::protobuf::int64 ByteCount() const;
};


       }
   }
}
